﻿package com.reyco1.util
{
	/*
	imports
	*/
   	import com.reyco1.events.IntervalEvent;
	import com.reyco1.extension.DispatchExtension;
    import flash.utils.*;
	/*
	class
	*/
	
	/**
	 * Based on a AS2 class written by Alex Toledo
	 */	
    public class IntervalUtil extends DispatchExtension
	{
		/*
		variables
		*/
		private static var NUM_TOTAL:Number;
        private var numDelay:Number;
		private var numID:uint;
		private var strName:String
		private var arrArguments:Array;
		private var funcToExecute:Function;
		private var funcOptional:Function;
		private var bolRunning:Boolean;
		private var numLoops:Number;
		private var numIndex:Number;
		private var numInterval:Number;
		private var arrOptionalFuncArgs:Array
        /*
		constructor
		*/
		
        /**
         * IntervalUtil construnctor
         * @param $name : name of the new Interval
         * @param $function : function to run at the interval rate
         * @param rest : arguments fo the sepecified function
         * 
         */		
        public function IntervalUtil($name:String, $function:Function = null, ... rest):void
		{
			NUM_TOTAL = 0 || NUM_TOTAL + 1;
			this.numID = NUM_TOTAL;
			this.strName = $name
			this.arrArguments = rest
			this.funcToExecute = $function
			this.bolRunning = false;
			this.numLoops = -1;
		}
		/*
		public functions
		*/
		
        /**
         * Initiates the interval
         * @param $intervalObject : object with a "delay" value in seconds and an optional "total" value which specified the total number of times the function should be run befor the interval stops.
         * @eventType com.reyco1.events.IntervalEvent.START
         */		
        public function start($intervalObject:Object):void
		{
			if (!this.bolRunning) {
				output("["+this.strName+"] " + "Start");
				this.numDelay = $intervalObject.delay * 1000;
				this.numInterval = setInterval(this.proxyFunction, this.numDelay);
				this.numLoops = $intervalObject.total || -1
				this.numIndex = 0;
				this.bolRunning = true;
				this.dispatchEvent(new IntervalEvent(IntervalEvent.START, this));
			}
		}
		
		/**
		 * Stops the interval
		 * @eventType com.reyco1.events.IntervalEvent.STOP
		 */		
		public function stop():void
		{
			if(this.funcOptional != null){
				this.funcOptional.apply(null, this.arrOptionalFuncArgs)
			}
			output("["+this.strName+"] " + "Stop");
			this.numIndex = 0;
			this.bolRunning = false;
			clearInterval(this.numInterval);
			this.dispatchEvent(new IntervalEvent(IntervalEvent.STOP, this));
		}
		
		/**
		 * @eventType com.reyco1.events.IntervalEvent.TRIGGER
		 * 
		 */		
		private function proxyFunction():void
		{
			if(this.funcToExecute != null){
				this.funcToExecute.apply(null, this.arrArguments);
			}
			this.numIndex++;
			if (this.numLoops > 0) {
				if (this.numIndex >= this.numLoops) {
					this.stop();
				}
			}
			this.dispatchEvent(new IntervalEvent(IntervalEvent.TRIGGER, this));
		}
		/*
		Property Definitions
		*/
		
		/**
		 * Returns the interval delay
		 * @return 
		 * 
		 */		
		public function get delay():Number
		{
			return (this.numDelay / 1000);
		}
		
		/**
		 * Returns a Boolean value specifying if the interval is running or not
		 * @return 
		 * 
		 */		
		public function get running():Boolean
		{
			return this.bolRunning;
		}
		
		/**
		 * Returns te elapsed time since the interval has been running
		 * @return 
		 * 
		 */		
		public function get elapsed():Number
		{
			return (this.numIndex * (this.numDelay / 1000));
		}
	}
}
